<?php
if (! defined('IN_WEB')) {
    exit('Access Denied');
}

//第一步、加载配置文件
define('BOOTSTRAP_CONFIGURATION', 0);

//第二步、加载数据基础类
define('BOOTSTRAP_DATABASE', 1);

//第三步、启动session
define('BOOTSTRAP_SESSION', 2);

//第四步、过滤输入数据
define('BOOTSTRAP_INPUT', 3);

//第五步、引入翻译机制
define('BOOTSTRAP_TRANSLATE', 4);

//第六步、引入smarty模板机制，设置输出页面头部为utf8
define('BOOTSTRAP_TEMPLATES', 5);

//第七步、路由机制，调用controller层中的类
define('BOOTSTRAP_ROUTER', 6);

//第八步、引用其他公共类库
define('BOOTSTRAP_FULL', 7);

define('DEFAULT_TIMEZONE', 'PRC');

function system_bootstrap ($phase = 0) {
    $phases = array(
        BOOTSTRAP_CONFIGURATION, 
        BOOTSTRAP_DATABASE, 
        BOOTSTRAP_SESSION, 
        BOOTSTRAP_INPUT, 
        BOOTSTRAP_TRANSLATE, 
        BOOTSTRAP_TEMPLATES, 
        BOOTSTRAP_ROUTER, 
        BOOTSTRAP_FULL
    );
    
    $stored_phase = - 1;
    while ($phases && $phase > $stored_phase) {
        $current_phase = array_shift($phases);
        if ($current_phase > $stored_phase) {
            $stored_phase = $current_phase;
        }
        switch ($current_phase) {
            case BOOTSTRAP_CONFIGURATION:
                //自定义php错误处理级别和错误处理方法
                if (! defined('DEVLOPMENT')) {
                    error_reporting(0);
                    set_error_handler('_custom_error_handler');
                    set_exception_handler('_custom_exception_handler');
                } else {
                    error_reporting(E_ALL & ~ E_NOTICE);
                }
                
                //由于Smarty.class.php中定义了spl_autoload_register('smartyAutoload');导致__autoload()方法失效
                spl_autoload_register('__autoload');
                
                //引入配置文件
                require_once (ROOT . '/config/config.inc.php');
                require_once (ROOT . '/config/define.inc.php');
                //根据配置文件设置时区
                $timezone = defined('TIMEZONE') ? TIMEZONE : DEFAULT_TIMEZONE;
                date_default_timezone_set($timezone);
                break;
            
            case BOOTSTRAP_DATABASE:
                require_once (ROOT . '/includes/database.inc');
                break;
            
            case BOOTSTRAP_SESSION:
                session_start();
                break;
            
            case BOOTSTRAP_INPUT:
                _init_input();
                break;
            
            case BOOTSTRAP_TRANSLATE:
                require_once (ROOT . '/includes/translate.inc');
                break;
            
            case BOOTSTRAP_TEMPLATES:
                require_once (ROOT . '/includes/smarty.inc');
                break;
            
            case BOOTSTRAP_ROUTER:
                require_once (ROOT . '/includes/router.inc');
                break;
            
            case BOOTSTRAP_FULL:
                
                break;
        }
    }
}

function _init_input () {
    $magic_quotes_gpc = function_exists('get_magic_quotes_gpc') &&
     get_magic_quotes_gpc();
    if (! $magic_quotes_gpc) {
        $_GET = _addslashes($_GET);
        $_POST = _addslashes($_POST);
        $_COOKIE = _addslashes($_COOKIE);
        $_FILES = _addslashes($_FILES);
    }
}

function _addslashes ($string) {
    if (is_array($string)) {
        $keys = array_keys($string);
        foreach ($keys as $key) {
            $val = $string[$key];
            unset($string[$key]);
            $string[addslashes($key)] = _addslashes($val);
        }
    } else {
        $str = addslashes($str);
    }
    return $string;
}

function __autoload ($className) {
    $info = _class_name_info($className);
    $classPath = ROOT . "/{$info['folder']}/{$className}.class.php";
    if (is_file($classPath)) {
        include ($classPath);
    }
}

//自定义php的错误处理方法
function _custom_error_handler ($errno, $errstr, $errfile, $errline) {
    //整理输出的内容
    if ($errno == E_NOTICE) return;
    $types = _error_levels();
    $severity_msg = $types[$errno] ? $types[$errno] : 'Unknown error';
    $message = "PHP $severity_msg : $errstr in File $errfile on Line $errline";
    //错误保存到文件中
    write_error_log($message);
}

function _custom_exception_handler ($exception) {
    $errstr = $exception->getMessage();
    $backtrace = $exception->getTrace();
    $errline = $exception->getLine();
    $errfile = $exception->getFile();
    $message = "Exception : $errstr in File $errfile on Line $errline";
    write_error_log($message);
    echo 'there is some error in the log';
    exit();
}

function write_error_log ($message) {
    $time = date('Y-m-d H:i:s');
    $message = "[ {$time} ] {$message}\n";
    $file = ROOT . './data/errorlog/' . date("Ym") . '_errorlog.php';
    error_log($message, 3, $file);
}

function _error_levels () {
    $types = array(E_ERROR => array('Error'), E_WARNING => array('Warning'), 
    E_PARSE => array('Parse error'), E_NOTICE => array('Notice'), 
    E_CORE_ERROR => array('Core error'), E_CORE_WARNING => array('Core warning'), 
    E_COMPILE_ERROR => array('Compile error'), 
    E_COMPILE_WARNING => array('Compile warning'), 
    E_USER_ERROR => array('User error'), E_USER_WARNING => array('User warning'), 
    E_USER_NOTICE => array('User notice'), E_STRICT => array('Strict warning'), 
    E_RECOVERABLE_ERROR => array('Recoverable fatal error'));
    // E_DEPRECATED and E_USER_DEPRECATED were added in PHP 5.3.0.
    if (defined('E_DEPRECATED')) {
        $types[E_DEPRECATED] = array('Deprecated function');
        $types[E_USER_DEPRECATED] = array('User deprecated function');
    }
    return $types;
}

function _class_name_info ($className) {
    $strlen = strlen($className);
    $tmp_arr = $info = array();
    if ($strlen > 0) {
        $tmp = '';
        for ($i = 0; $i < $strlen; $i ++) {
            $tmpChar = $className[$i];
            if ($tmpChar == strtoupper($tmpChar)) {
                $tmp && $tmp_arr[] = $tmp;
                $tmp = $tmpChar;
            } else {
                $tmp .= $tmpChar;
            }
        }
        $info['folder'] = strtolower($tmp);
        $info['filename'] = $className;
    }
    return $info;
}

function random ($length, $numeric = 0) {
    if ($numeric) {
        $hash = sprintf('%0' . $length . 'd', mt_rand(0, pow(10, $length) - 1));
    } else {
        $hash = '';
        $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
        $max = strlen($chars) - 1;
        for ($i = 0; $i < $length; $i ++) {
            $hash .= $chars[mt_rand(0, $max)];
        }
    }
    return $hash;
}

function check_post ($fields = array()) {
    if ($fields) {
        foreach ($fields as $f) {
            $value = trim($_POST[$f]);
            if ($value == '') {return $f;}
        }
    }
    return '1';
}

function chinese_substr ($text, $start, $length = NULL, $ex = 2) {
    $strlen = strlen($text);
    // Find the starting byte offset
    $bytes = 0;
    if ($start > 0) {
        // Count all the continuation bytes from the start until we have found
        // $start characters
        $bytes = - 1;
        $chars = - 1;
        while ($bytes < $strlen && $chars < $start) {
            $bytes ++;
            $c = ord($text[$bytes]);
            if ($c < 0x80 || $c >= 0xC0) {
                if ($c >= 0xC0) {
                    $chars += $ex;
                } else {
                    $chars ++;
                }
            }
        }
    } else if ($start < 0) {
        // Count all the continuation bytes from the end until we have found
        // abs($start) characters
        $start = abs($start);
        $bytes = $strlen;
        $chars = 0;
        while ($bytes > 0 && $chars < $start) {
            $bytes --;
            $c = ord($text[$bytes]);
            if ($c < 0x80 || $c >= 0xC0) {
                if ($c >= 0xC0) {
                    $chars += $ex;
                } else {
                    $chars ++;
                }
            }
        }
    }
    $istart = $bytes;
    
    // Find the ending byte offset
    if ($length === NULL) {
        $bytes = $strlen - 1;
    } else if ($length > 0) {
        // Count all the continuation bytes from the starting index until we have
        // found $length + 1 characters. Then backtrack one byte.
        $bytes = $istart;
        $chars = 0;
        while ($bytes < $strlen && $chars < $length) {
            $bytes ++;
            $c = ord($text[$bytes]);
            if ($c < 0x80 || $c >= 0xC0) {
                if ($c >= 0xC0) {
                    $chars += $ex;
                } else {
                    $chars ++;
                }
            }
        }
        $bytes --;
    } else if ($length < 0) {
        // Count all the continuation bytes from the end until we have found
        // abs($length) characters
        $length = abs($length);
        $bytes = $strlen - 1;
        $chars = 0;
        while ($bytes >= 0 && $chars < $length) {
            $c = ord($text[$bytes]);
            if ($c < 0x80 || $c >= 0xC0) {
                if ($c >= 0xC0) {
                    $chars += $ex;
                } else {
                    $chars ++;
                }
            }
            $bytes --;
        }
    }
    $iend = $bytes;
    
    return substr($text, $istart, max(0, $iend - $istart + 1));
}

function show_404_page($content=null){
    header('HTTP/1.1 404 Not Found');
    header("status: 404 Not Found");
    echo $content? $content: 'page not found';
    exit();
}

function image_rename_rule(){
    static $count;
    $count ++;
    return 'image_'.time().'_'.intval($_SESSION['uid']).'_'.$count;
}